#include"thread.h"
#define  ARG_MAX  10
#define BUFF_SIZE 1024

char* get_cmd(char buff[],char *myargv[])
{
	if(buff==NULL || myargv==NULL) return NULL;

	int i=0;
	char *ptr=NULL;
	char *s=strtok_r(buff," ",&ptr);
	while(s!=NULL)
	{
		myargv[i++]=s;
		s=strtok_r(NULL," ",&ptr);
	}
	return myargv[0];//return rm
}

int run_cmd(int c,char* myargv[])
{
	if(c<0 || myargv==NULL) return -1;

	int pipefd[2];
	if(pipe(pipefd)==-1)
	{
		return -1;
	}

	pid_t pid=fork();
	if(pid==-1)
	{
		return -1;
	}

	if(pid==0)
	{
		close(pipefd[0]);//关闭读端
		dup2(pipefd[1],1);//覆盖标准输出1
		dup2(pipefd[1],2);//覆盖标准错误输出2
		execvp(myargv[0],myargv);
		perror("run cmd err");
		exit(0);
	}
	else//父进程
	{
		close(pipefd[1]);
		wait(NULL);
		char read_buff[1024]={"ok#"};
		read(pipefd[0],read_buff+3,1024-3);
		send(c,read_buff,strlen(read_buff),0);
		close(pipefd[0]);


	}
}

void send_file(int c,char* filename)
{
	if(filename==NULL) 
	{
		send(c,"err",3,0);//有待修改
		return;
	}

	//get a.c
	int fd=open(filename,O_RDONLY);
	if(fd==-1)
	{
		send(c,"err",3,0); 
		return;
	}

	//回复文件大小，确认是否下载
	int file_size=lseek(fd,0,SEEK_END);
	lseek(fd,0,SEEK_SET);

	char status_buff[64]={0};
	//ok#4325
	sprintf(status_buff,"ok#%d",file_size);
	send(c,status_buff,strlen(status_buff),0);

	memset(status_buff,0,64);
	int num=recv(c,status_buff,64,0);
	if(num<=0)
	{
		return;
	}
	if(strcmp(status_buff,"ok#")!=0)
	{
		close(fd);
		return;
	}

	char data[BUFF_SIZE];
	while( (num=read(fd,data,BUFF_SIZE)) > 0)
	{
		send(c,data,num,0);
	}

	close(fd);
	return;
}

void recv_file(int c,char* filename)
{
	if(filename==NULL)
	{
		//send(c,"err",3,0);
		return;
	}

	//up a.c
	//int fd=open(filename,O_RDONLY);
	if(access(filename,F_OK)==0)//文件已存在
	{
		send(c,"err",3,0);
		return;
	}

	//接收文件
	int fd=open(filename,O_WRONLY|O_CREAT,0600);
	if(fd==-1)
	{
		send(c,"err",3,0);
		return;
	}

	send(c,"ok",2,0);

	char tmp_buff[64]={0};
	int num=recv(c,tmp_buff,64,0);
	if(num<=0)
	{
		send(c,"err",3,0);
		return;
	}

	int filesize=atoi(tmp_buff+3);

	send(c,"ok",2,0);//可以接收

	char data[1024]={0};
	int curr_size=0;
	while(1)
	{
		num=recv(c,data,1024,0);
		if(num<=0)
		{
			send(c,"err",3,0);
			break;
		}
		
		write(fd,data,num);

		curr_size+=num;
		if(curr_size>=filesize)
		{
			send(c,"ok",2,0);
			break;
		}

	}
	
	close(fd);
}

void* work_thread(void* arg)
{
	int c=(int)arg;

	while(1)
	{
		char buff[128]={0};
		int num=recv(c,buff,127,0);//1 rm a.c   2 get a.c  3 up a.c
		if(num<=0)
		{
			break;
		}

		//test
		//send(c,"ok",2,0);
		
		//解析客户端命令
		char* myargv[ARG_MAX]={0};//数组的每一个是个数组
		char *cmd=get_cmd(buff,myargv);
		if(cmd==NULL)
		{
			send(c,"err",3,0);//出错
			continue;
		}

		if(strcmp(cmd,"get")==0)
		{
			//load
			send_file(c,myargv[1]);//发送文件,myargv[0]=get myargv[1]=a.c(文件名)
		}
		else if(strcmp(cmd,"up")==0)
		{
			//upload
			recv_file(c,myargv[1]);//上传文件
		}
		else
		{
			//fork()+exec()
			if(-1==run_cmd(c,myargv))
			{
				send(c,"err",3,0);
			}
		}




	}

	close(c);
	printf("client close\n");
}
void thread_start(int c)
{
	pthread_t id;
	pthread_create(&id,NULL,work_thread,(void*)c);
}

	
